////////////////////////////////////////////////////////////////////////////////
//
//  Copyright 2010 galaxy.org
//
//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the License.
//  You may obtain a copy of the License at
//
//  http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////

package org.galaxy.richflex.collections
{
	import mx.utils.ObjectUtil;

	/**
	 * This is a simple map implementation. A map is a set of Key-Value tuples.
	 * In <code>KVMap</code>, it is simply put Key-Value tuples into an object
	 * instance. Keys must be strings and values can be any subclasses of <code>Object</code>.
	 * If values with the same key are put into one <code>KVMap</code>, the old value
	 * will be replaced by the new one.
	 * 
	 * @author Cheng Liang
	 * 
	 * @version 0.0.1 create 2010-9-28
	 */
	public class KVMap
	{
		/**
		 * @private
		 */
		private var internalObject : Object = {};
		
		/**
		 * Constructor.
		 */
		public function KVMap()
		{
		}
		
		/**
		 * Puts Key-Value tuple into this map. The new value will replace the old one
		 * which keys are the same.
		 * 
		 * @param k the key to this value
		 * @param v the value that put into this map
		 * 
		 * @return true if the key is a new one, that is not replacement happens
		 */
		public function put(k : String, v : Object) : Boolean
		{
			var keyExists : Boolean = containsKey(k);
			internalObject[k] = v;
			return keyExists;
		}
		
		/**
		 * Gets value to the key.
		 * 
		 * @param k key to get
		 * 
		 * @return value to this key
		 */
		public function getValue(k : String) : Object
		{
			return internalObject[k];
		}
		
		/**
		 * Tests if the map contains the key.
		 * 
		 * @param k key to test
		 * 
		 * @return true if the map contains this key
		 */
		public function containsKey(k : String) : Boolean
		{
			return (k in internalObject);
		}
		
		/**
		 * Clears key and its value. Note that this operation will not remove event listeners
		 * or other functions from the value object so further work might need.
		 * 
		 * @param k key to clear
		 * 
		 * @return true if clears successfully; otherwise if cannot clear this key
		 * and its value or not such key, return false
		 */
		public function clearKey(k : String) : Boolean
		{
			if(containsKey(k)) {
				return (delete internalObject.k);
			} else {
				return false;
			}
		}
		
		/**
		 * Clear all keys and values. Note that this operation will only clear all keys and their
		 * values, not remove event listeners or other functions from the value object 
		 * so further work might need.
		 */
		public function clearAll() : void
		{
			internalObject = {};
		}
		
		/**
		 * Gets keys set.
		 * 
		 * @return keys set in this map
		 */
		public function keySet() : Array
		{
			return ObjectUtil.getClassInfo(internalObject, ["mx_internal_uid"])["properties"];
		}
		
	}
}